﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RMS.Utils.EventAggregators
{
    public abstract class BaseEvent<TPayload> : BaseEvent
    {
        protected BaseEvent()
        {
        }

        public virtual bool Contains(Action<TPayload> subscriber)
        {

            IEventSubscription eventSubscription;

            lock (Subscriptions)
            {
                eventSubscription = Subscriptions.Cast<EventSubscription<TPayload>>().FirstOrDefault(evt => evt.Action == subscriber);
            }

            return eventSubscription != null;
        }

        public virtual void Publish(TPayload payload)
        {
            base.Publish(new object[] { payload });
        }

        public virtual SubscriptionToken Subscribe(Action<TPayload> action)
        {
            return this.Subscribe(action, false);
        }

        public virtual SubscriptionToken Subscribe(Action<TPayload> action, bool keepSubscriberReferenceAlive)
        {
            return this.Subscribe(action, keepSubscriberReferenceAlive, delegate
            {
                return true;
            });
        }

        public virtual SubscriptionToken Subscribe(Action<TPayload> action, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter)
        {
            IDelegateReference actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);
            IDelegateReference filterReference = new DelegateReference(filter, keepSubscriberReferenceAlive);
            EventSubscription<TPayload> eventSubscription = new EventSubscription<TPayload>(actionReference, filterReference);
            return base.Subscribe(eventSubscription);
        }

        public virtual void Unsubscribe(Action<TPayload> subscriber)
        {
            Func<EventSubscription<TPayload>, bool> func = null;
            lock (base.Subscriptions)
            {
                if (func == null)
                {
                    //<>c__DisplayClassc<TPayload> classc;
                    //func = new Func<EventSubscription<TPayload>, bool>(classc, (IntPtr) this.<Unsubscribe>b__a);
                }
                IEventSubscription item = Enumerable.FirstOrDefault<EventSubscription<TPayload>>(base.Subscriptions.Cast<EventSubscription<TPayload>>(), func);
                if (item != null)
                {
                    base.Subscriptions.Remove(item);
                }
            }
        }
    }
}
